package com.employment.controller;

import com.employment.common.R;
import com.employment.dto.*;
import com.employment.entity.ChatConversation;
import com.employment.entity.ChatMessage;
import com.employment.service.ChatService;
import com.employment.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.employment.websocket.ChatWebSocketHandler;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;

/**
 * 聊天控制器
 * 
 * @author employment
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/chat")
@Tag(name = "聊天管理")
@Validated
public class ChatController {
    
    @Autowired
    private ChatService chatService;
    
    @Operation(summary = "创建会话")
    @PostMapping("/conversation")
    public R<ChatConversationDTO> createConversation(@Valid @RequestBody CreateConversationRequest request) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            
            ChatConversation conversation;
            if (request.getConversationType() == 1) {
                // 创建私聊
                conversation = chatService.createPrivateConversation(currentUserId, request.getOtherUserId());
            } else {
                // 创建群聊
                conversation = chatService.createGroupConversation(
                    currentUserId, 
                    request.getConversationName(), 
                    request.getAvatar(), 
                    request.getParticipantIds()
                );
            }
            
            // 转换为DTO
            ChatConversationDTO conversationDTO = convertToConversationDTO(conversation);
            
            return R.success(conversationDTO);
            
        } catch (Exception e) {
            log.error("创建会话失败", e);
            return R.error("创建会话失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "获取会话列表")
    @GetMapping("/conversations")
    public R<List<ChatConversationDTO>> getConversations() {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            List<ChatConversation> conversations = chatService.getUserConversations(currentUserId);
            
            // 转换为DTO列表
            List<ChatConversationDTO> conversationDTOs = conversations.stream()
                .map(this::convertToConversationDTO)
                .collect(java.util.stream.Collectors.toList());
            
            return R.success(conversationDTOs);
            
        } catch (Exception e) {
            log.error("获取会话列表失败", e);
            return R.error("获取会话列表失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "发送消息")
    @PostMapping("/message")
    public R<ChatMessageDTO> sendMessage(@Valid @RequestBody SendMessageRequest request) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            
            ChatMessage message = chatService.sendMessage(
                request.getConversationId(),
                currentUserId,
                request.getMessageType(),
                request.getContent(),
                request.getFileUrl(),
                request.getFileName(),
                request.getFileSize(),
                request.getLocationInfo()
            );
            
            // 推送消息到WebSocket
            ChatWebSocketHandler.pushNewMessage(message);
            
            // 转换为DTO
            ChatMessageDTO messageDTO = convertToMessageDTO(message);
            
            return R.success(messageDTO);
            
        } catch (Exception e) {
            log.error("发送消息失败", e);
            return R.error("发送消息失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "获取聊天记录")
    @GetMapping("/messages/{conversationId}")
    public R<List<ChatMessageDTO>> getMessages(
            @PathVariable Long conversationId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer size) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            
            // 检查用户是否是会话参与者
            if (!chatService.isConversationParticipant(conversationId, currentUserId)) {
                return R.error("无权限查看该会话");
            }
            
            List<ChatMessage> messages = chatService.getConversationMessages(conversationId, page, size);
            
            // 转换为DTO列表
            List<ChatMessageDTO> messageDTOs = messages.stream()
                .map(this::convertToMessageDTO)
                .collect(java.util.stream.Collectors.toList());
            
            return R.success(messageDTOs);
            
        } catch (Exception e) {
            log.error("获取聊天记录失败", e);
            return R.error("获取聊天记录失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "标记消息已读")
    @PutMapping("/message/{messageId}/read")
    public R<Void> markAsRead(@PathVariable Long messageId) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            chatService.markAsRead(messageId, currentUserId);
            
            return R.success();
            
        } catch (Exception e) {
            log.error("标记消息已读失败", e);
            return R.error("标记消息已读失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "撤回消息")
    @PutMapping("/message/{messageId}/recall")
    public R<Void> recallMessage(@PathVariable Long messageId) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            chatService.recallMessage(messageId, currentUserId);
            
            return R.success();
            
        } catch (Exception e) {
            log.error("撤回消息失败", e);
            return R.error("撤回消息失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "设置会话置顶")
    @PutMapping("/conversation/{conversationId}/pin")
    public R<Void> pinConversation(@PathVariable Long conversationId, @RequestParam Boolean isPinned) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            chatService.pinConversation(conversationId, currentUserId, isPinned);
            
            return R.success();
            
        } catch (Exception e) {
            log.error("设置会话置顶失败", e);
            return R.error("设置会话置顶失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "设置会话免打扰")
    @PutMapping("/conversation/{conversationId}/mute")
    public R<Void> muteConversation(@PathVariable Long conversationId, @RequestParam Boolean isMuted) {
        try {
            Long currentUserId = SecurityUtil.getCurrentUserId();
            chatService.muteConversation(conversationId, currentUserId, isMuted);
            
            return R.success();
            
        } catch (Exception e) {
            log.error("设置会话免打扰失败", e);
            return R.error("设置会话免打扰失败：" + e.getMessage());
        }
    }
    
    @Operation(summary = "获取在线用户数")
    @GetMapping("/online-count")
    public R<Integer> getOnlineCount() {
        try {
            int count = ChatWebSocketHandler.getOnlineUserCount();
            return R.ok(count);
            
        } catch (Exception e) {
            log.error("获取在线用户数失败", e);
            return R.error("获取在线用户数失败：" + e.getMessage());
        }
    }
    
    /**
     * 转换会话实体为DTO
     */
    private ChatConversationDTO convertToConversationDTO(ChatConversation conversation) {
        ChatConversationDTO dto = new ChatConversationDTO();
        dto.setConversationId(conversation.getConversationId());
        dto.setConversationType(conversation.getConversationType());
        dto.setConversationName(conversation.getConversationName());
        dto.setAvatar(conversation.getAvatar());
        dto.setCreateTime(conversation.getCreateTime());
        
        // TODO: 设置其他字段，如最后一条消息、未读数等
        
        return dto;
    }
    
    /**
     * 转换消息实体为DTO
     */
    private ChatMessageDTO convertToMessageDTO(ChatMessage message) {
        ChatMessageDTO dto = new ChatMessageDTO();
        dto.setMessageId(message.getMessageId());
        dto.setConversationId(message.getConversationId());
        dto.setSenderId(message.getSenderId());
        dto.setMessageType(message.getMessageType());
        dto.setContent(message.getContent());
        dto.setFileUrl(message.getFileUrl());
        dto.setFileName(message.getFileName());
        dto.setFileSize(message.getFileSize());
        dto.setLocationInfo(message.getLocationInfo());
        dto.setIsRead(message.getIsRead() != null && message.getIsRead() == 1);
        dto.setIsRecalled(message.getIsRecalled());
        dto.setRecallTime(message.getRecallTime());
        dto.setCreateTime(message.getCreateTime());
        
        // TODO: 设置发送者信息
        
        return dto;
    }
}